package com.lpb.spring.lpbspring.ioc;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.Closeable;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;

/**
 * ioc容器 bean工厂的默认实现 需要包含以下功能
 * 1、注册bean信息
 * 2、生成bean对象
 * 3、获取bean对象的功能
 * 4、销毁bean对象
 *
 * @ClassName DefaultBeanFactory
 * @Description TODO
 * 迭代日志
 *       v0：最基础的版本
 *           1、接口beandefinition里面存储bean的定义信息
 *           2、类GenericBeanDefinition是类beanbdefinition的默认实现
 *           3、接口BeanDefinitionRegistr的功能是提供beandifinition的注册、获取、判断是否存在的功能
 *           4、接口BeanFactory的功能及ioc容器的基本功能 getbean
 *           5、类defaultBeanFactory需要提供beandifinition的注册 和 获取bean的功能  等于是将BeanDefinitionRegistr和BeanFactory定义的功能整合
 *              所以defaultBeanFactory 需要实现这两个接口，并且需要使用map来作为beandifinition存储的容器 以及 还有一个单例bean存储的容器
 *           6、PreBuildBeanFactory类的作用是实现提前实例化单例bean
 *
 *       v1：新增bean别名
 *          新增bean的别名 一个bean对象可以有很多别名，别名也可以有别名，定义typeNameMap来存储benanane的别名
 *
 *       v2、增加带范型的getBean方法
 *           新增typeNameMap类存储class和beanname的映射关系，这里注意因为一个类可以有子类 所以一个class可以对应有多个bean
 *           这里在beandefinition里新增里primary判断是否是主类 getbean只会实例化主类
 *
 *       v3、新增构造注入
 *           beandefinition里新增 获取bean构造参数列表的方法
 *           DefaultBeanFactory里createInstancec创建实例的方法需要兼容 如果设置里bean的构造参数 就使用带参数的构造方法，包括静态工厂和普通工厂方法构造
 *           为了优化每次创建实例都要获取构造方法的过程 可以将第一次获取到的构造方法或者静态工厂方法和普通工厂成员方法缓存到beandefinition
 *           对于引用类型的参数需要 我们需要从ioc容器里面找，所以创建一个BeanReference对象 来包装被ioc管理的引用类型的参数
 *
 *      v4、新增循环依赖检测
 *           思路：使用threadLocal保存当前正在创建的bean，创建之前判断如果这个bean已存在 那么就报错。创建完成从threadLocal中remove移除
 *              threadLocal存beanName
 *
 *      v5、新增属性注入
 *           思路：定义类PropertyValue,用来存放属性和属性值。需要在beandefinition中存放PropertyValue
 *                然后在创建完instance后 使用反射进行属性值的set
 *
 *      v6、新增属性注入过程中循环依赖问题的解决
 *           思路：在创建完instance后  属性注入前，提前暴露instance，这里使用map来存储beanname和instance的映射
 *                在get方法中需要判断如果某个bean是提前暴露来 就直接返回。
 *                这里注意在属性注入完成后需要把提前暴露的bean删掉
 *                需要将这个map放在ThreadLocal中 保证线程私有
 *                注意！！！构造注入形成的循环依赖是无法解决的 这个直接在循环依赖检测的时候报错。spring也是同样报错。
 *
 *       v7、新增aop
 *           知识点：1、advice 通知，即要增强的内容
 *                  2、join points 连接点，即供我们可选择的类的切入点
 *                  3、pointcut 切入点，即我们选择的切入点 就是具体对哪个方法进行增强
 *                  4、aspect  切面 advice+pointcut=一个切面
 *                  5、weaving 织入 即把要增强的内容 在切入点进行实现 且不改变切入点的原代码（框架来实现）
 *                  6、introduction 引入，新添加的方法
 *
 * @date 2022/11/22 18:04
 * @Version 1.0
 * @authoe linpengbo
 */
public class DefaultBeanFactory implements BeanFactory, BeanDefinitionRegistry, Closeable {
    /**
     * 注册的bean信息都放在这里
     */
    Map<String, BeanDefinition> beanDefinitionMap = Maps.newConcurrentMap();

    //缓存单例的集合
    Map<String, Object> singletonBeanMap = Maps.newConcurrentMap();

    //存储类型和beanName的映射关系
    Map<Class<?>, Set<String>> typeNameMap = Maps.newConcurrentMap();

    //key：bean名称  value：bean的别名
    Map<String, Set<String>> aliasMap = Maps.newConcurrentMap();

    ThreadLocal<Set<String>> createBeanRecord=new ThreadLocal<>();

    //存放提前暴露的bean
    ThreadLocal<Map<String,Object>> earlyExposeBuildingBeans=new ThreadLocal<>();

    private List<BeanPostProcessor> beanPostProcessors = Collections.synchronizedList(new ArrayList<>());

    @Override
    public void registerBeanPostProcess(BeanPostProcessor bpp) {
        this.beanPostProcessors.add(bpp);
        //TODO 这里bpp可能是beanpostprocessor和beanfactoryAware接口的子类
        if (bpp instanceof BeanFactoryAware) {
            ((BeanFactoryAware) bpp).setBeanFactory(this);
        }
    }

    @Override
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws Exception {
        Objects.requireNonNull(beanName, "注册bean定义信息时，beanName不能为空");//断言
        Objects.requireNonNull(beanDefinition, "注册bean定义信息时，bean定义信息不能为空");
        //bean定义信息的校验
        if (!beanDefinition.validate()) {
            throw new Exception("有问题");
        }
        //判重 spring可配置允许bean重复覆盖
        if (this.beanDefinitionMap.containsKey(beanName)) {
            throw new Exception("bean已存在");

        }
        //注册
        this.beanDefinitionMap.put(beanName, beanDefinition);
    }

    @Override
    public BeanDefinition getBeanDefinition(String beanName) throws Exception {
        if (this.isAlias(beanName)) {
            beanName = this.getOriginalName(beanName);
        }
        return this.beanDefinitionMap.get(beanName);
    }

    @Override
    public boolean containsBeanDefinition(String beanName) throws Exception {
        if (this.isAlias(beanName)) {
            beanName = this.getOriginalName(beanName);
        }
        return this.beanDefinitionMap.containsKey(beanName);
    }

    /**
     * 生成bean 然后返回
     *
     * @param beanName
     * @return
     * @throws Exception
     */
    @Override
    public Object getBean(String beanName) throws Exception {
        if (this.isAlias(beanName)) {
            beanName = this.getOriginalName(beanName);
        }
        return doGetBean(beanName);
    }


    private Object doGetBean(String beanName) throws Exception {
        Objects.requireNonNull(beanName, "构造bean-bean名称不能为空");
        //对于单例的处理-如果已经存在 那么直接返回不用重新生成对象了
        Object instance = singletonBeanMap.get(beanName);
        if (instance != null) {
            return instance;
        }
        //提前暴露的bean如果存在 直接返回
        instance=this.getEarlyExposeBean(beanName);
        if(instance!=null){
            return instance;
        }
        Set<String> beanRecordSet = createBeanRecord.get();
        if(beanRecordSet==null){
            beanRecordSet=Sets.newHashSet();
            createBeanRecord.set(beanRecordSet);
        }
        if(beanRecordSet.contains(beanName)){
            throw new Exception("产生循环依赖,"+beanName+" 正在创建过程中");
        }
        beanRecordSet.add(beanName);
        BeanDefinition beanDefinition = this.beanDefinitionMap.get(beanName);
        Objects.requireNonNull(beanDefinition, "构造bean-bean的定义信息不能为空");
        //对于单例的处理-如果bean是单例那么这里需要加锁-同一个jvm里只允许一个线程初始化bean成功
        if (beanDefinition.isSingleton()) {
            synchronized (singletonBeanMap) {
                instance = this.singletonBeanMap.get(beanName);
                if (instance == null) {//双重检查
                    instance = doCreateInstance(beanName,beanDefinition);
                    this.singletonBeanMap.put(beanName, instance);
                }
            }
        } else {
            instance = doCreateInstance(beanName,beanDefinition);
        }
        //创建完成移除
        beanRecordSet.remove(beanName);
        return instance;
    }


    private Object doCreateInstance(String beanName,BeanDefinition beanDefinition) throws Exception {
        Class<?> beanClass = beanDefinition.getBeanClass();
        Object instance = null;
        if (beanClass != null) {
            if (StringUtils.isBlank(beanDefinition.getFactoryMethodName())) {
                //使用构造方法来生成对象
                instance = this.createInstanceByConstructor(beanDefinition);
            } else {
                //使用静态工厂方法
                instance = this.createInstanceByStaticFactoryMethod(beanDefinition);
            }
        } else {
            //使用工厂bean方式生成对象
            instance = this.createInstanceByFactoryBean(beanDefinition);
        }

        //提前暴露
        this.doEarlyExposeBeans(beanName,instance);

        //属性注入
        this.setterDi(beanDefinition,instance);

        //清除提前暴露的对象
        this.removeEarlyExposeBeans(beanName);

        //执行初始化方法
        this.doInit(beanDefinition, instance);
        return instance;
    }


    /**获取提前暴露的bean
     * @param beanName
     * @return
     */
    private Object getEarlyExposeBean(String beanName) {
        Map<String, Object> earlyExposeBeanMap = this.earlyExposeBuildingBeans.get();
        if(earlyExposeBeanMap!=null){
            return earlyExposeBeanMap.get(beanName);
        }
        return null;
    }


    /**清除提前暴露的bean
     * @param beanName
     */
    private void removeEarlyExposeBeans(String beanName) {
        Map<String, Object> earlyExposeBeanMap = this.earlyExposeBuildingBeans.get();
        if(earlyExposeBeanMap.containsKey(beanName)){
            earlyExposeBeanMap.remove(beanName);
        }
    }


    /**提前暴露bean
     * @param instance
     */
    private void doEarlyExposeBeans(String beanName,Object instance) {
        Map<String, Object> earlyExposeBeanMap= this.earlyExposeBuildingBeans.get();
        if(earlyExposeBeanMap==null){
            earlyExposeBeanMap=Maps.newHashMap();
            this.earlyExposeBuildingBeans.set(earlyExposeBeanMap);
        }
        earlyExposeBeanMap.put(beanName,instance);
    }

    /**属性注入
     * @param beanDefinition
     * @param instance
     */
    private void setterDi(BeanDefinition beanDefinition, Object instance)throws Exception {
        List<PropertyValue> propertyValues = beanDefinition.getPropertyValues();
        if(CollectionUtils.isEmpty(propertyValues)){
            return;
        }
        for (PropertyValue value:propertyValues ) {
            String name = value.getName();
            if(StringUtils.isBlank(name)){
                continue;
            }
            //获取对应字段
            Field field = instance.getClass().getDeclaredField(name);
            //放置字段是私有的
            field.setAccessible(true);
            Object realValue = this.getRealValue(value.getValue());
            //赋值
            field.set(instance,realValue);
        }
    }

    //使用构造方法来生成对象
    private Object createInstanceByConstructor(BeanDefinition beanDefinition) {
        try {
            //获取构造函数入参
            Object[] valueArr = this.getConstructorArgumentValues(beanDefinition);
            //获取合适的构造函数
            Constructor<?> constructor = determineConstructor(beanDefinition, valueArr);
            return constructor.newInstance(valueArr);
        } catch (Exception e) {
            System.out.println("构造bean对象异常");
        }
        return null;
    }


    /**
     * 获取构造函数
     *
     * @param bd
     * @param args
     * @return
     * @throws Throwable
     */
    private Constructor<?> determineConstructor(BeanDefinition bd, Object[] args) throws Exception {
        //1、如果参数列表为null那么直接返回无参构造
        if (args == null) {
            return bd.getBeanClass().getConstructor(null);
        }
        Constructor<?> ct = bd.getConstructor();
        //2、如果包含有缓存的构造函数 那么就使用缓存的
        if (ct != null) {
            return ct;
        }
        //3、使用参数类型精确匹配构造函数
        Class<?>[] paramTypeArr = new Class[args.length];
        for (int i = 0; i < args.length; i++) {
            paramTypeArr[i] = args[i].getClass();
        }
        try {
            ct = bd.getBeanClass().getConstructor(paramTypeArr);
        } catch (Exception e) {

        }

        //4、如果精确匹配不成功（可能的情况是一个类的属性定义的是父类，而对应参数传递的是子类，使用精确匹配会不成功）
        //拿到所有的构造方法 遍历找

        if (ct == null) {
            Constructor<?>[] constructors = bd.getBeanClass().getConstructors();
            // 判断逻辑：先判断参数数量，再依次比对形参类型与实参类型
            outer:
            for (Constructor<?> ct0 : constructors) {
                Class<?>[] paramterTypes = ct0.getParameterTypes();
                if (paramterTypes.length == args.length) {   //通过参数数量过滤
                    for (int i = 0; i < paramterTypes.length; i++) { //再依次比对形参类型与实参类型是否匹配
                        if (!paramterTypes[i].isAssignableFrom(args[i].getClass())) {
                            continue outer; //参数类型不可赋值（不匹配），跳到外层循环，继续下一个
                        }
                    }
                    ct = ct0;  //匹配上了
                    break outer;
                }
            }
        }

        if (ct == null) {
            throw new Exception("没有找到bean的构造函数");
        }
        //原型模式下缓存构造函数
        if(bd.isPrototype()){
            bd.setConstructor(ct);
        }

        return ct;
    }


    /**
     * 获取bean定义信息里的 构造函数入参
     *
     * @param bd
     * @return
     * @throws Exception
     */
    private Object[] getConstructorArgumentValues(BeanDefinition bd) throws Exception {
        List<?> constructorArgumentValues = bd.getConstructorArgumentValues();
        if (CollectionUtils.isEmpty(constructorArgumentValues)) {
            return null;
        }
        Object[] argArr = new Object[constructorArgumentValues.size()];
        int i = 0;
        for (Object cav : constructorArgumentValues) {
            argArr[i++] = getRealValue(cav);
        }
        return argArr;
    }

    /**
     * 获取参数真实值-这里主要解决BeanReference包装的引用类型参数
     *
     * @param cav
     * @return
     * @throws Exception
     */
    private Object getRealValue(Object cav) throws Exception {
        Object obj = null;
        if (cav != null) {
            if (cav instanceof BeanReference) {
                BeanReference reference = (BeanReference) cav;
                if (StringUtils.isNotBlank(reference.getBeanName())) {
                    obj = this.getBean(reference.getBeanName());
                } else if (reference.getType() != null) {
                    obj = this.getBean(reference.getType());
                }
            } else if (cav instanceof Object[]) {
                // TODO 处理集合中的bean引用
                Object[] parmArr = (Object[]) cav;
                int i = 0;
                for (Object pram : parmArr) {
                    parmArr[i++] = getRealValue(pram);
                }
                obj = parmArr;
            } else if (cav instanceof Collection) {
                // TODO 处理集合中的bean引用
            } else if (cav instanceof Properties) {
                // TODO 处理properties中的bean引用
            } else if (cav instanceof Map) {
                // TODO 处理Map中的bean引用
            } else {
                obj = cav;
            }
        }
        return obj;
    }


    //使用静态工厂方法 这里BeanDefinition里的beanclass是工程bean的class类型
    private Object createInstanceByStaticFactoryMethod(BeanDefinition beanDefinition) throws Exception {

        //获取工厂方法的入参
        Object[] argArr = this.getConstructorArgumentValues(beanDefinition);
        //找到带参数的工厂方法
        Method method=this.determineFactoryMethod(beanDefinition,argArr,beanDefinition.getBeanClass());

        //这个class对象是 这个工厂对象的class对象
        //Class<?> beanClass = beanDefinition.getBeanClass();
        //Method method = beanClass.getMethod(beanDefinition.getFactoryMethodName(), null);
        return method.invoke(beanDefinition.getBeanClass(), null);
    }


    //获取对应的工厂方法
    private Method determineFactoryMethod(BeanDefinition bd, Object[] args,Class<?> beanClass) throws Exception{
        Method method=null;
        if(args==null){
            method=beanClass.getDeclaredMethod(bd.getFactoryMethodName(),null);
            return method;
        }
        //取缓存
        method= bd.getFactoryMethod();
        if(method!=null){
            return method;
        }
        //3、使用参数类型精确匹配
        Class<?>[] paramTypeArr = new Class[args.length];
        for (int i = 0; i < args.length; i++) {
            paramTypeArr[i] = args[i].getClass();
        }
        try {
            method = beanClass.getDeclaredMethod(bd.getFactoryMethodName(),paramTypeArr);
        } catch (Exception e) {

        }
        if(method==null){
            //遍历找
            Method[] declaredMethods = beanClass.getDeclaredMethods();
          out: for (Method m:declaredMethods) {
              Class<?>[] parameterTypes = m.getParameterTypes();
              if(bd.getFactoryMethodName().equals(m.getName())&&paramTypeArr.length==parameterTypes.length){
                  for (int i = 0; i <parameterTypes.length ; i++) {
                      //但凡有一个参数类型不匹配 外层循环直接continue
                       if(!paramTypeArr[i].getClass().isAssignableFrom(parameterTypes[i].getClass())){
                           continue out;
                       }
                  }
                  method=m;
                  break;
              }
          }
        }

        if(method==null){
            throw new Exception("没找到对应的工厂方法");
        }
        //原型模式缓存工厂方法
        if(bd.isPrototype()){
            bd.setFactoryMethod(method);
        }
        return method;
    }


    //使用工厂bean方式生成对象
    private Object createInstanceByFactoryBean(BeanDefinition beanDefinition) throws Exception {
        //先获取这个工厂对象
        Object factoryBean = this.doGetBean(beanDefinition.getFactoryBeanName());
        //获取工厂方法的入参
        Object[] argArr = this.getConstructorArgumentValues(beanDefinition);
        //获取对应的工厂方法
        Method method = this.determineFactoryMethod(beanDefinition, argArr, factoryBean.getClass());

        //Method method = factoryBean.getClass().getMethod(beanDefinition.getFactoryMethodName(), null);
        return method.invoke(factoryBean, method);
    }





    /**
     * bean对象的初始化方法
     *
     * @param bd
     * @param instance
     * @throws Exception
     */
    private void doInit(BeanDefinition bd, Object instance) throws Exception {
        if (StringUtils.isBlank(bd.getInitMethodName())) {
            return;
        }
        Method method = instance.getClass().getMethod(bd.getInitMethodName(), null);
        method.invoke(instance, null);
    }


    @Override
    public <T> T getBean(Class<T> type) throws Exception {
       /*
		逻辑：
		1 获得其对应的所有的BeanDefinition
		2 如果只有一个，直接获取bean实例返回，否则
		3 遍历找出Primary的
		4 如果primary没有，或大于1个，抛出异常
		5 返回Primary的实例
		 */
        Set<String> names = this.typeNameMap.get(type);
        if (names != null) {
            if (names.size() == 1) {
                return (T) this.getBean(names.iterator().next());
            } else {
                //找Primary
                BeanDefinition bd = null;
                String primaryName = null;
                StringBuilder nameStrings = new StringBuilder();
                for (String name : names) {
                    bd = this.getBeanDefinition(name);
                    if (bd != null && bd.isPrimary()) {
                        if (primaryName != null) {
                            String mess = type + " 类型的Bean存储多个Primary[" + primaryName + "," + name + "]";
                            throw new Exception(mess);
                        } else {
                            primaryName = name;
                        }
                    }
                    nameStrings.append(" " + name);
                }

                if (primaryName != null) {
                    return (T) this.getBean(primaryName);
                } else {
                    String mess = type + " 类型的Bean存在多个[" + nameStrings + "] 但无法确定Primary";
                    throw new Exception(mess);
                }
            }
        }
        return null;
    }

    @Override
    public <T> Map<String, T> getBeansOfType(Class<T> clazz) throws Exception {
        Set<String> clazzNameSet = this.typeNameMap.get(clazz);
        if (CollectionUtils.isNotEmpty(clazzNameSet)) {
            Map<String, T> map = Maps.newHashMap();
            for (String beanName : clazzNameSet) {
                map.put(beanName, (T) this.getBean(beanName));
            }
            return map;
        }
        return null;
    }

    @Override
    public <T> List<T> getBeansOfTypeList(Class<T> type) throws Exception {
        Set<String> beanNameSet = this.typeNameMap.get(type);
        List<T> resultList=Lists.newArrayList();
        if(CollectionUtils.isEmpty(beanNameSet)){
            return resultList;
        }
        for (String beanName:beanNameSet) {
            resultList.add((T)this.getBean(beanName));
        }
        return resultList;
    }

    @Override
    public Class<?> getType(String beanName) throws Exception {
        BeanDefinition beanDefinition = this.getBeanDefinition(beanName);
        Class<?> type = beanDefinition.getBeanClass();
        if (type != null) {
            if (StringUtils.isBlank(beanDefinition.getFactoryMethodName())) {//说明不是通过静态工厂方法构造  是根据构造方法构造

            } else {
                //是通过静态工厂方法构造，此时的type是工厂类的class对象，我们需要拿到这个静态方法的返回值 就是目标bean对象
                Method method = type.getDeclaredMethod(beanDefinition.getFactoryMethodName(), null);
                type = method.getReturnType();
            }
        } else {
            //通过普通工厂方法构造 此时也需要拿到这个工厂对象 再拿到方法的返回值
            type = this.getType(beanDefinition.getFactoryBeanName());
            Method method = type.getDeclaredMethod(beanDefinition.getFactoryMethodName(), null);
            type = method.getReturnType();
        }
        return type;
    }


    public void registerTypeMap() throws Exception {
        Map<String, BeanDefinition> beanDefinitionMap = this.beanDefinitionMap;
        for (String beanName : beanDefinitionMap.keySet()) {
            Class<?> type = this.getType(beanName);
            //注册本类
            this.registerTypeMap(beanName, type);
            //注册父类
            this.registerSuperClassTypeMap(beanName, type);
            //注册接口
            this.registerInterfaceTypeMap(beanName, type);
        }
    }


    //注册类和实现的接口类型映射关系
    private void registerInterfaceTypeMap(String name, Class<?> type) {
        Class<?>[] interfaces = type.getInterfaces();
        if (interfaces != null && interfaces.length > 0) {
            for (Class clazz : interfaces) {
                this.registerTypeMap(name, clazz);
                //递归找父接口
                this.registerInterfaceTypeMap(name, clazz);
            }
        }
    }

    private void registerSuperClassTypeMap(String name, Class<?> type) {
        Class<?> superclass = type.getSuperclass();
        if (superclass != null && !Object.class.equals(superclass)) {
            this.registerTypeMap(name, superclass);

            //递归找父类
            this.registerSuperClassTypeMap(name, superclass);
            //找父接口
            this.registerInterfaceTypeMap(name, superclass);
        }
    }


    private void registerTypeMap(String name, Class<?> type) {
        Set<String> names2type = this.typeNameMap.get(type);
        if (names2type == null) {
            names2type = new HashSet<>();
            this.typeNameMap.put(type, names2type);
        }
        names2type.add(name);
    }


    @Override
    public void registerAlias(String name, String alias) throws Exception {
        Objects.requireNonNull(StringUtils.isBlank(name), "请指定正确的bean名称");
        Objects.requireNonNull(StringUtils.isBlank(alias), "请指定正确的bean的别名名称");
        if (!this.beanDefinitionMap.containsKey(name)) {
            throw new Exception("bean未注册,无法设置别名");
        }
        for (Map.Entry<String, Set<String>> entry : this.aliasMap.entrySet()) {
            if (entry.getValue().contains(alias)) {
                throw new Exception("别名已存在");
            }
        }
        if (this.aliasMap.containsKey(name)) {
            this.aliasMap.get(name).add(alias);
            return;
        }
        this.aliasMap.put(name, Sets.newHashSet(alias));
    }

    @Override
    public void removeAlias(String alias) throws Exception {
        Objects.requireNonNull(StringUtils.isBlank(alias), "请指定正确的bean的别名名称");
        for (Map.Entry<String, Set<String>> entry : this.aliasMap.entrySet()) {
            if (entry.getValue().contains(alias)) {
                entry.getValue().remove(alias);
                this.aliasMap.put(entry.getKey(), entry.getValue());
            }
        }
    }

    @Override
    public boolean isAlias(String name) throws Exception {
        Objects.requireNonNull(StringUtils.isBlank(name), "请指定正确的bean的别名名称");
        boolean flag = false;
        for (Map.Entry<String, Set<String>> entry : this.aliasMap.entrySet()) {
            if (entry.getValue().contains(name)) {
                flag = true;
                break;
            }
        }
        return flag;
    }

    @Override
    public String getOriginalName(String name) throws Exception {
        Objects.requireNonNull(StringUtils.isBlank(name), "请指定正确的bean的别名名称");
        String beanName = null;
        for (Map.Entry<String, Set<String>> entry : this.aliasMap.entrySet()) {
            if (entry.getValue().contains(name)) {
                beanName = entry.getKey();
                break;
            }
        }
        return null;
    }

    @Override
    public Set<String> getAlias(String name) throws Exception {
        return this.aliasMap.get(name);
    }

    /**
     * bean销毁的逻辑就在这里
     *
     * @throws IOException
     */
    @Override
    public void close() throws IOException {

    }


}
